﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.FxCop.Sdk;
using System.IO;
using System.Diagnostics;
using System.Reflection;

namespace SPDisposeCheckRules.Rules
{
    class SPDisposeCheck : SPDisposeCheckBaseRule
    {
        const string SECTION_TERMINATOR = "----------------------------------------------------------";

        public SPDisposeCheck()
            : base("SPDisposeCheck")
        {
        }

        public override ProblemCollection Check(ModuleNode moduleNode)
        {
            AssemblyNode assembly = moduleNode.ContainingAssembly;
            ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo("\"" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\SPDisposeCheck.exe" + "\"", "\"" + assembly.Location + "\"");
            info.UseShellExecute = false;
            info.ErrorDialog = false;
            info.CreateNoWindow = true;
            info.RedirectStandardOutput = true;
            try
            {
                Process process = System.Diagnostics.Process.Start(info);
                StreamReader standardOutput = process.StandardOutput;
                string returnString = standardOutput.ReadToEnd();
                standardOutput.Close();

                if (returnString.Contains("Total Found: 0") == false)
                {
                    using (StringReader reader = new StringReader(returnString))
                    {
                        string line;
                        string id = string.Empty;
                        string module = string.Empty;
                        string method = string.Empty;
                        string statement = string.Empty;
                        string source = string.Empty;
                        string lineNumber = string.Empty;
                        string notes = string.Empty;
                        string moreInfo = string.Empty;

                        while ((line = reader.ReadLine()) != null)
                        {
                            if (line.Contains("ID: SPDisposeCheckID"))
                            {
                                id = line.Replace("ID: ", "");
                                module = string.Empty;
                                method = string.Empty;
                                statement = string.Empty;
                                source = string.Empty;
                                lineNumber = string.Empty;
                                notes = string.Empty;
                                moreInfo = string.Empty;
                            }
                            if (line.Contains("Module: "))
                            {
                                module = line.Replace("Module: ", "");
                            }
                            if (line.Contains("Method: "))
                            {
                                method = line.Replace("Method: ", "");
                            }
                            if (line.Contains("Statement: "))
                            {
                                statement = line.Replace("Statement: ", "");
                            }
                            if (line.Contains("Source: "))
                            {
                                source = line.Replace("Source: ", "");
                            }
                            if (line.Contains("Line: "))
                            {
                                lineNumber = line.Replace("Line: ", "");
                            }
                            if (line.Contains("Notes: "))
                            {
                                notes = line.Replace("Notes: ", "");
                            }

                            if (line == SECTION_TERMINATOR)
                            {
                                if (id.Contains("SPDisposeCheckID"))
                                {
                                    if (lineNumber != string.Empty)
                                {
                                    Problem spDisposeProblem = new Problem(this.GetResolution(id, notes, method, statement), module, Int32.Parse(lineNumber));
                                    this.Problems.Add(spDisposeProblem);
                                }
                                else
                                {
                                    Problem spDisposeProblem = new Problem(this.GetResolution(id, notes, method, statement), assembly.Location, 0);
                                    this.Problems.Add(spDisposeProblem);
                                }
                                id = string.Empty;
                                }
                            }
                        }
                    } 
                }
            }
            catch
            {
                //Blinky light make bad thing happen.
            }

            return this.Problems;
        }
    }
}
